﻿using Newtonsoft.Json;
using SpaceNeedle.SDK.WindowsPhone;
using SpaceNeedle.x6473.WindowsPhone.Models;
using SpaceNeedle.x6473.WindowsPhone.ViewModels;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Resources;
using Windows.ApplicationModel;
using Windows.Storage;

namespace SpaceNeedle.x6473.WindowsPhone.Common
{
    public class Api
    {
        private static string endpointUri = "http://6473.azurewebsites.net/api/";

        public static async Task<Me> GetMe(string userId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<Me>(endpointUri + "me/" + userId, "GET", null, null, null);

            if (result.Status == 200)
            {
                return result.Content;
            }

            return null;
        }

        public static async Task<bool> SetPushNotificationChannelUri(Me me, Uri channelUri)
        {
            try
            {
                if (me == null || channelUri == null)
                {
                    return false;
                }

                string b64channel = Convert.ToBase64String(new UTF8Encoding().GetBytes(channelUri.ToString()));
                string deviceId = Convert.ToBase64String(new UTF8Encoding().GetBytes(AppViewModel.Instance.Properties.DeviceId));
                
                //string b64channel = HttpUtility.UrlEncode(Convert.ToBase64String(new UTF8Encoding().GetBytes(channelUri.ToString())));
                //string deviceId = HttpUtility.UrlEncode(Convert.ToBase64String(new UTF8Encoding().GetBytes(AppViewModel.Instance.Properties.DeviceId)));
                //var result = await new WebRequest().DownloadApiStringAsync<bool>(endpointUri + "me/" + me.Id + "/push/wp8/" + b64channel + "/" + deviceId, "POST", null, null, null);

                DeviceInfo info = new DeviceInfo();
                info.PushId = channelUri.ToString();
                info.DeviceId = AppViewModel.Instance.Properties.DeviceId;
                info.Platform = "WP8";

                string json = JsonConvert.SerializeObject(info);

                var result = await new WebRequest().DownloadApiStringAsync<bool>(endpointUri + "me/" + me.Id + "/push", "POST", null, json, null);

                if (result.Status == 200)
                {
                    return result.Content;
                }
            }
            catch { }

            return false;
        }

        public static async Task<List<Guid>> GetRequestItemSupporters(Guid requestItemId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<List<Guid>>(endpointUri + "requestitems/" + requestItemId.ToString() + "/supporters", "GET", null, null, null);

            if (result.Status == 200)
            {
                return result.Content;
            }

            return null;
        }

        public static async Task<int> GetRequestItemSupportersCount(Guid requestItemId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<int>(endpointUri + "requestitems/" + requestItemId.ToString() + "/supporters/count", "GET", null, null, null);

            if (result.Status == 200)
            {
                return result.Content;
            }

            return 0;
        }

        public static async Task<ObservableCollection<RequestItem>> GetRequestItemsSupportedByUser(Guid userId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<ObservableCollection<RequestItem>>(endpointUri + "requestitems/supportedby/" + userId.ToString(), "GET", null, null, null);

            if (result.Status == 200)
            {
                return result.Content;
            }

            return null;
        }

        public static async Task<bool> AddRequestItemSupporter(Guid requestItemId, Guid userId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<int>(endpointUri + "requestitems/" + requestItemId + "/supporters/add/" + userId.ToString(), "POST", null, null, null);

            if (result.Status == 200)
            {
                return true;
            }

            return false;
        }

        public static async Task<bool> DeleteRequestItemSupporter(Guid requestItemId, Guid userId)
        {
            var result = await new WebRequest().DownloadApiStringAsync<int>(endpointUri + "requestitems/" + requestItemId + "/supporters/delete/" + userId.ToString(), "POST", null, null, null);

            if (result.Status == 200)
            {
                return true;
            }

            return false;
        }

        public static async Task<ObservableCollection<Phone>> LoadPhones()
        {
            var result = await new WebRequest().DownloadApiStringAsync<ObservableCollection<Phone>>(endpointUri + "phones", "GET", null, null, null);

            if (result.Status == 200)
            {
                return result.Content;
            }

            return null;
        }

        public static async Task<ObservableCollection<Request>> LoadRequests()
        {
            var result3 = await new WebRequest().DownloadApiStringAsync<ObservableCollection<Request>>(endpointUri + "requests", "GET", null, null, null);

            if (result3.Status == 200)
            {
                return result3.Content;
            }

            return null;
        }

        public static async Task<ObservableCollection<Alert>> LoadAlerts()
        {
            var result2 = await new WebRequest().DownloadApiStringAsync<ObservableCollection<Alert>>(endpointUri + "alerts", "GET", null, null, null);

            if (result2.Status == 200)
            {
                ObservableCollection<Alert> alerts = new ObservableCollection<Alert>();

                foreach (var alert in result2.Content.OrderByDescending(x=>x.CreationDate))
                {
                    if(alert.CreationDate >= AppViewModel.Instance.Properties.AlertsBeginDate)
                    {
                        alerts.Add(alert);
                    }
                }

                return alerts;
            }

            return null;
        }

        public static async Task<AppContent> LoadAppContent()
        {
            try
            {
                if (AppViewModel.Instance.Properties.CanLoadOnlineAppContent)
                {
                    var result0 = await new WebRequest().DownloadApiStringAsync<AppContent>(endpointUri + "appcontents/pt-br", "GET", null, null, null);

                    if (result0.Status == 200)
                    {
                        return result0.Content;
                    }
                }
                
                string json = await AppServices.Current.StorageService.ReadAppFileStringAsync("Resources\\AppContent.json");

                return JsonConvert.DeserializeObject<AppContent>(json);
            }
            catch (Exception ex)
            {
                int a = 0;
            }

            return null;
        }

        public static async Task<ObservableCollection<RequestItem>> LoadUserRequests()
        {
            var result4 = await new WebRequest().DownloadApiStringAsync<ObservableCollection<RequestItem>>(endpointUri + "requestitems?user=" + System.Net.HttpUtility.UrlEncode(AppViewModel.Instance.Properties.Me.Id.ToString()), "GET", null, null, null);

            if (result4.Status == 200)
            {
                return result4.Content;
            }

            return null;
        }

        public static async Task<ObservableCollection<RequestItem>> LoadAllRequests()
        {
            var result4 = await new WebRequest().DownloadApiStringAsync<ObservableCollection<RequestItem>>(endpointUri + "requestitems", "GET", null, null, null);

            if (result4.Status == 200)
            {
                return result4.Content;
            }

            return null;
        }
    }
}
